/*
 * 김환태
 * 140424
 */

package Stream;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class Memo extends JFrame {

	static String fileName = "NoName";//파일의 이름
	static boolean modifyFlag = false;//수정 여부
	String oriStr="";//파일을 로드했을때 원본파일을 저장
	int oriLength = 0;//원본파일의 길이를 저장
	
	private JPanel contentPane;
	private JLabel status;
	private JScrollPane scrollPane;
	private JTextArea result;
	private JMenuBar menuBar;
	private JMenu mnNewMenu;
	private JMenuItem mntmNewMenuItem;
	private JMenuItem mntmNewMenuItem_1;
	private JMenuItem mntmNewMenuItem_2;
	private JMenuItem mntmNewMenuItem_3;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Memo frame = new Memo();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Memo() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 451, 355);
		setJMenuBar(getMenuBar_1());
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		contentPane.add(getStatus(), BorderLayout.SOUTH);
		contentPane.add(getScrollPane(), BorderLayout.CENTER);
		setTitle("파일명 : "+ fileName);
	}

	public void newFile() throws Exception {
		int yn = -1;
		if (modifyFlag) {// 현재 파일의 내용이 수정된 경우
			yn = JOptionPane.showConfirmDialog(null, "파일이 변경되었습니다. 저장하시겠습니까?");
			if (yn == JOptionPane.YES_NO_OPTION)
				save(); // 예스를 눌렀을경우 save()메서드를 실행시켜 저장
		}
		fileName = "NoName";
		modifyFlag = false;
		result.setText("");
		oriLength = 0;
		oriStr ="";
		setTitle("파일명 : " + fileName);
		
	}
	
	public void load() throws Exception{//모든 Exception를 던진다.
		int yn = -1;
		if(modifyFlag){//현재 파일의 내용이 수정된 경우
			yn = JOptionPane.showConfirmDialog(null, "파일이 변경되었습니다. 저장하시겠습니까?");
			if(yn == JOptionPane.YES_NO_OPTION) save(); // 예스를 눌렀을경우 save()메서드를 실행시켜 저장
		}
		// 저장된 이후이거나, 파일이 없거나..
		JFileChooser fc = new JFileChooser(fileName);
		yn = fc.showOpenDialog(this);// 버튼눌럿을때의 상수값을 yn에 저장
		if (yn == JFileChooser.APPROVE_OPTION) {// 열기버튼을 눌럿을때 APPROVE_OPTION의
												// 상수값과 같냐.(같으면 true)
			File f = fc.getSelectedFile();
			fileName = f.getPath();// getPath : 경로정보
			setTitle("파일명 : " + fileName);
			
			FileReader fr = new FileReader(fileName);
			BufferedReader br = new BufferedReader(fr);
			
			result.setText("");
			while(true){
				String str = br.readLine();//한줄단위로 읽어들임
				if(str==null) break;
				result.append(str + "\n");
			}
			br.close();
			fr.close();
			
			oriLength = result.getText().length(); //로드를 한후 TextArea의 글의 길이를 저장
			oriStr = result.getText();//로드를 한 후 TextArea의 글을 가져와서 저장
			
			result.setCaretPosition(result.getText().length());
		}
	}
	
	public void save() throws Exception{
		if(fileName.equals("NoName"))saveAs();//파일이름이 NoName인경우는 한번도 저장한적이 없다는 것이기 때문에 새로 저장하는 메서드인 saveAs()실행
		FileWriter fw = new FileWriter(fileName);
		BufferedWriter bw = new BufferedWriter(fw);
		
		bw.write(result.getText());
		status.setText("파일이 저장되었습니다.");
		
		bw.close();
		fw.close();
	}
	
	public void saveAs() throws Exception{
		JFileChooser fc = new JFileChooser(fileName);
		int yn = fc.showSaveDialog(this);
		if(yn == JFileChooser.APPROVE_OPTION){
			File f = fc.getSelectedFile();
			fileName = f.getPath();
			
			save();
		}
	}
	
	private JLabel getStatus() {
		if (status == null) {
			status = new JLabel(" ");
		}
		return status;
	}
	private JScrollPane getScrollPane() {
		if (scrollPane == null) {
			scrollPane = new JScrollPane();
			scrollPane.setViewportView(getResult());
		}
		return scrollPane;
	}
	private JTextArea getResult() {
		if (result == null) {
			result = new JTextArea();
			result.addKeyListener(new KeyAdapter() {
				@Override
				public void keyReleased(KeyEvent ev) {
//					status.setText("Char = "+ev.getKeyChar()+" code = "+ev.getKeyCode());
					if(!modifyFlag){
						if(result.getText().length() != oriLength) modifyFlag = true;
						if(result.getText() != oriStr) modifyFlag = true;
						oriStr=null;//기존에 저장되어있던 값은 가비지 컬렉션에 의해 지워짐
					}
					if(modifyFlag){
						setTitle("파일명 : "+ fileName + " *");
					}
				}
			});
			result.setLineWrap(true);
		}
		return result;
	}
	private JMenuBar getMenuBar_1() {
		if (menuBar == null) {
			menuBar = new JMenuBar();
			menuBar.add(getMnNewMenu());
		}
		return menuBar;
	}
	private JMenu getMnNewMenu() {
		if (mnNewMenu == null) {
			mnNewMenu = new JMenu("파일");
			mnNewMenu.add(getMntmNewMenuItem_3());
			mnNewMenu.add(getMntmNewMenuItem());
			mnNewMenu.add(getMntmNewMenuItem_1());
			mnNewMenu.add(getMntmNewMenuItem_2());
		}
		return mnNewMenu;
	}
	private JMenuItem getMntmNewMenuItem() {
		if (mntmNewMenuItem == null) {
			mntmNewMenuItem = new JMenuItem("읽기");
			mntmNewMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					try {
						load();
					} catch (Exception ex) {
						status.setText(ex.toString());
					}
				}
			});
		}
		return mntmNewMenuItem;
	}
	private JMenuItem getMntmNewMenuItem_1() {
		if (mntmNewMenuItem_1 == null) {
			mntmNewMenuItem_1 = new JMenuItem("저장");
			mntmNewMenuItem_1.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					try {
						save();
					} catch (Exception ex) {
						status.setText(ex.toString());
					}
				}
			});
		}
		return mntmNewMenuItem_1;
	}

	private JMenuItem getMntmNewMenuItem_2() {
		if (mntmNewMenuItem_2 == null) {
			mntmNewMenuItem_2 = new JMenuItem("새 저장");
			mntmNewMenuItem_2.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					try {
						saveAs();
					} catch (Exception ex) {
					}
				}
			});
		}
		return mntmNewMenuItem_2;
	}
	private JMenuItem getMntmNewMenuItem_3() {
		if (mntmNewMenuItem_3 == null) {
			mntmNewMenuItem_3 = new JMenuItem("새 파일");
			mntmNewMenuItem_3.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					try {
						newFile();
					} catch (Exception ex) {
						status.setText(ex.toString());
					}
				}
			});
		}
		return mntmNewMenuItem_3;
	}
}
